import type { ArticleStyles, ArticleStylesKeys } from "@/store/modules/types";
import { v4 as uuidv4 } from "uuid";
import { rangeHandler } from "./range";
import { useArticleStore } from "@/store/modules/article";

type HighLightOptions = {
  color: string;
  bgColor: string;
};

const DefaultHighLightOptions = {
  color: "#000",
  bgColor: "#b2d7fd",
};
const articleStore = useArticleStore();

class TextStyleModifier {
  private static readonly articleStyles: MyPartial<
    MyRecord<keyof ArticleStyles, string | Function>
  > = {
    deleteLine: `text-decoration: line-through;`,
    underLine: "text-decoration: underLine;",
    note: (options: HighLightOptions) =>
      `background-color:${options.bgColor}; color:${options.color}`,
    bold: "font-weight: bold;",
    // background: (bgColor: string) => `background-color:${bgColor};`,
    // color: (color: string) => `color:${color};`,
  };

  static getSelectedTextContent() {
    return document.getSelection()?.toString() ?? "";
  }

  private static generateUUid(): string {
    return uuidv4();
  }

  static modifyElementStyle(
    selector: string,
    options: HighLightOptions = DefaultHighLightOptions
  ) {
    const ele = document.querySelector(selector) as HTMLElement;
    if (!ele) {
      console.error(`Element with selector "${selector}" not found.`);
      return;
    }
    ele.style.color = options.color;
    ele.style.backgroundColor = options.bgColor;
  }

  static modifySelectedTextRangeStyle(
    selectedText: string,
    hoverBarType: ArticleStylesKeys,
    options: HighLightOptions = DefaultHighLightOptions
  ) {
    const regex = new RegExp(signTranslateRegExp(selectedText), "g");

    const textContent = articleStore.getCurrentArticle!.textContent;
    let matchList = Array.from(textContent.matchAll(regex));
    matchList = matchList.map((match) => ({
      ...match,
      endIndex: match.index + match[0].length,
    }));
    console.log(matchList, "matchList");

    if (matchList.length <= 1) {
      return this.handleToHtmlFromSingleMatchText(regex, hoverBarType, options);
    } else {
      return this.handleToHtmlFromMoreMatchText(
        regex,
        matchList,
        hoverBarType,
        options
      );
    }
  }

  private static handleToHtmlFromSingleMatchText(
    regex: RegExp,
    hoverBarType: ArticleStylesKeys,
    options: any = DefaultHighLightOptions
  ) {
    const htmlContent = articleStore.getCurrentArticle!.htmlContent;
    let uuid = this.generateUUid();
    const styleInfo = this.articleStyles[hoverBarType]!;
    const style =
      typeof styleInfo === "string" ? styleInfo : styleInfo(options);

    const changedContent = htmlContent.replace(
      regex,
      `<span style="${style}" id="${uuid}">$&</span>`
    );

    return {
      uuid,
      changedContent,
    };
  }

  private static handleToHtmlFromMoreMatchText(
    regex: RegExp,
    matchList: RegExpExecArray[],
    hoverBarType: ArticleStylesKeys,
    options: any = DefaultHighLightOptions
  ) {
    const cursorOffset = rangeHandler.getCursorOffset();
    const toChangeMatchIndex = matchList.findIndex(
      (match) => match.index === cursorOffset
    );

    console.log({
      toChangeMatchIndex,
      matchList,
      cursorOffset,
    });

    const uuid = this.generateUUid();
    let matchCount = 0;

    const htmlContent = articleStore.getCurrentArticle!.htmlContent;
    const changedContent = htmlContent.replace(regex, (match) => {
      if (matchCount++ === toChangeMatchIndex) {
        const styleInfo = this.articleStyles[hoverBarType]!;
        const style =
          typeof styleInfo === "string" ? styleInfo : styleInfo(options);
        return `<span style="${style}" id="${uuid}">${match}</span>`;
      }
      return match;
    });
    return {
      uuid,
      changedContent,
    };
  }
}

const textStyleModifier = new TextStyleModifier();
export { textStyleModifier, TextStyleModifier };
